package CustomUI;

import java.util.ArrayList;

import org.Consts;
import org.Utility;

import com.ydev.graphics.animations.R;

import DTO.DrawingActionDTO;
import DTO.DrawingPlaneDTO;
import GameTools.ydMath;
import GameTools.ydPoint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path.Direction;
import android.graphics.Path;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;

public class TransformationToolsView extends View {
	
	DrawingPlaneDTO drawingPlane;
	DrawingActionDTO dA;
	
	String action = "";// Consts.TRANSFORMATION_ACTIONS_MOVE;
	ydPoint clickedAt = new ydPoint();
	ydPoint deltaPoint = new ydPoint();
	ydPoint previousDeltaPoint = new ydPoint();

	ydOnTouchListeners listeners = new ydOnTouchListeners();

	Bitmap img;
	Paint paint;

	Matrix matrix;

	ydPoint canvasSize;
	
	Path outline;
	Paint fgPaintSel = new Paint();

	public TransformationToolsView(Context context) {
		super(context);
		init();
	}

	public TransformationToolsView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public TransformationToolsView(Context context, AttributeSet attrs,
			int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	public void init() {

		img = BitmapFactory.decodeResource(getResources(),
				R.drawable.drawing_tools_move_normal);

		paint = new Paint();

		matrix = new Matrix();

		outline= new Path();
		
		fgPaintSel.setARGB(255, 0, 0,0);
		fgPaintSel.setStyle(Style.STROKE);
		fgPaintSel.setPathEffect(new DashPathEffect(new float[] {10,20}, 0));
		
		listeners.addOnTouchListener(new View.OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				float x = event.getX();
				float y = event.getY();				
				matrix.reset();
				matrix.setTranslate(canvasSize.x / 2-img.getWidth()/2, canvasSize.y / 2-img.getHeight()/2);
				if (action.equals(Consts.DRAWING_ACTIONS_MOVE)) {
					if (event.getAction() == MotionEvent.ACTION_DOWN) {
						dA = new DrawingActionDTO(
								action, 0,
								0);
						drawingPlane.addAction(dA);
						clickedAt.setCoordinates(x, y);
					} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
						deltaPoint.reverseDirection();
						/*drawingPlane.boundTL.deltaMove(deltaPoint);
						drawingPlane.boundBR.deltaMove(deltaPoint);*/
						deltaPoint.setCoordinates(x - clickedAt.x, y
								- clickedAt.y);
						//clickedAt.setCoordinates(x, y);
					} else if (event.getAction() == MotionEvent.ACTION_UP) {
						deltaPoint.reverseDirection();
						/*drawingPlane.boundTL.deltaMove(deltaPoint);
						drawingPlane.boundBR.deltaMove(deltaPoint);*/
						deltaPoint.setCoordinates(x - clickedAt.x, y
								- clickedAt.y);
						//clickedAt.setCoordinates(x, y);
					}
					Log.d("deltaPoint", deltaPoint.toString());
					dA.deltaMove(deltaPoint);
					dA.translate.setCoordinates(deltaPoint);
					matrix.postTranslate(deltaPoint.x, deltaPoint.y);
				/*	drawingPlane.boundTL.deltaMove(deltaPoint);
					drawingPlane.boundBR.deltaMove(deltaPoint);*/
					invalidate();
					return true;
				} else if (action.equals(Consts.DRAWING_ACTIONS_ROTATE)) {
					
					if (event.getAction() == MotionEvent.ACTION_DOWN) {
						dA = new DrawingActionDTO(
								action, 0,
								0);
						drawingPlane.addAction(dA);
						clickedAt.setCoordinates(x, y);
						deltaPoint.setCoordinates(x, y);
					} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
						/*ydPoint midPoint=ydMath.midPoint(drawingPlane.boundTL, drawingPlane.boundBR);
						float w=ydMath.vectorToDegrees(new ydPoint(deltaPoint.x-midPoint.x, deltaPoint.y-midPoint.y));
						drawingPlane.boundTL.rotate(midPoint, -w);
						drawingPlane.boundBR.rotate(midPoint, -w);*/
						deltaPoint.setCoordinates(x-clickedAt.x, y-clickedAt.y);
						//clickedAt.setCoordinates(x, y);
					} else if (event.getAction() == MotionEvent.ACTION_UP) {
						/*ydPoint midPoint=ydMath.midPoint(drawingPlane.boundTL, drawingPlane.boundBR);
						float w=ydMath.vectorToDegrees(new ydPoint(deltaPoint.x-midPoint.x, deltaPoint.y-midPoint.y));
						drawingPlane.boundTL.rotate(midPoint, -w);
						drawingPlane.boundBR.rotate(midPoint, -w);*/
						deltaPoint.setCoordinates(x-clickedAt.x, y-clickedAt.y);
						//clickedAt.setCoordinates(x, y);
					}
					deltaPoint.setCoordinates(x, y);
					ydPoint midPoint=ydMath.midPoint(drawingPlane.boundTL, drawingPlane.boundBR);
					float w=ydMath.vectorToDegrees(new ydPoint(deltaPoint.x-midPoint.x, deltaPoint.y-midPoint.y));
					Log.d("Slope", (new ydPoint(deltaPoint.x-midPoint.x, deltaPoint.y-midPoint.y)).toString());
					dA.pivot.setCoordinates(midPoint);
					dA.rads=w;
					/*drawingPlane.boundTL.rotate(midPoint, w);
					drawingPlane.boundBR.rotate(midPoint, w);*/
					matrix.postRotate(w, canvasSize.x/2,canvasSize.y/2);
					
					invalidate();
					return true;
				} else if (action.equals(Consts.DRAWING_ACTIONS_SCALE)) {
					if (event.getAction() == MotionEvent.ACTION_DOWN) {
						dA = new DrawingActionDTO(
								action, 0,
								0);
						drawingPlane.addAction(dA);
						clickedAt.setCoordinates(x, y);
						deltaPoint.setCoordinates(x - clickedAt.x, y
								- clickedAt.y);
					} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
						deltaPoint.setCoordinates(x - clickedAt.x, y
								- clickedAt.y);
						clickedAt.setCoordinates(x, y);
					} else if (event.getAction() == MotionEvent.ACTION_UP) {
						deltaPoint.setCoordinates(x -clickedAt.x, y
								- clickedAt.y);
						clickedAt.setCoordinates(x, y);
					}
					deltaPoint.setCoordinates(x , y);
					//deltaPoint.setCoordinates(200 , 200);
					float deltaX=(float) ((deltaPoint.x-drawingPlane.boundTL.x)/( drawingPlane.boundBR.x-drawingPlane.boundTL.x));
					float deltaY=(float) ((deltaPoint.y-drawingPlane.boundTL.y)/( drawingPlane.boundBR.y-drawingPlane.boundTL.y));
					dA.scale.setCoordinates(deltaX, deltaY);
					//drawingPlane.boundBR.deltaMove(clickedAt);
					Log.d("Scale", dA.scale.toString());
					invalidate();
					return true;
				}
				return false;
			}
		});

		this.setOnTouchListener(listeners);
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		canvasSize = new ydPoint(w, h);

		matrix.setTranslate(canvasSize.x / 2, canvasSize.y / 2);
	}

	public void setAction(String action) {
		this.action = action;
		clickedAt.setCoordinates(0, 0);
		deltaPoint.setCoordinates(0, 0);

		if (action.equals(Consts.DRAWING_ACTIONS_MOVE)) {
			img = BitmapFactory.decodeResource(getResources(),
					R.drawable.drawing_tools_move_normal);
		} else if (action.equals(Consts.DRAWING_ACTIONS_ROTATE)) {
			img = BitmapFactory.decodeResource(getResources(),
					R.drawable.rotate);
		} else if (action.equals(Consts.DRAWING_ACTIONS_SCALE)) {
			img = BitmapFactory.decodeResource(getResources(),
					R.drawable.drawing_tools_scale_normal);
		}
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);

		/*if (img != null)
			canvas.drawBitmap(img, matrix, paint);*/
		
		if(outline!=null){
			canvas.drawPath(outline, fgPaintSel);
		}
		canvas.drawARGB(128, 0, 0, 0);
	}

	public String getAction() {
		return action;
	}

	public ydPoint getShift() {
		return deltaPoint;
	}

	public void addOnTouchListener(OnTouchListener onTouchListener) {
		listeners.addOnTouchListener(onTouchListener);
	}

	public void setDrawingPlane(DrawingPlaneDTO drawingPlane) {
		this.drawingPlane=drawingPlane;
		
/*		drawingPlane.boundTL=new ydPoint(1000, 1000);
		drawingPlane.boundBR=new ydPoint(0, 0);
		
		ArrayList<ydPoint> pathPoints=new ArrayList<ydPoint>();
		
		for(DrawingActionDTO da: drawingPlane.drawingActions){
			if(da.action.equals(Consts.DRAWING_ACTIONS_BRUSH) || da.action.equals(Consts.DRAWING_ACTIONS_Shape) 
					|| da.action.equals(Consts.DRAWING_ACTIONS_TEXT)){
				pathPoints=Utility.pathToArrayList(da.path);
				
				for( ydPoint point: pathPoints){
					if(point.x>drawingPlane.boundBR.x){
						drawingPlane.boundBR.x=point.x;
					}
					if(point.x<drawingPlane.boundTL.x){
						drawingPlane.boundTL.x=point.x;
					}
					
					if(point.y>drawingPlane.boundBR.y){
						drawingPlane.boundBR.y=point.y;
					}
					if(point.y<drawingPlane.boundTL.y){
						drawingPlane.boundTL.y=point.y;
					}
				}
				
			}
			
			
		}*/
		
		/*outline.reset();
		outline.addRect(drawingPlane.boundTL.x, drawingPlane.boundTL.y, drawingPlane.boundBR.x, drawingPlane.boundBR.y, Direction.CCW);
		outline.transform(drawingPlane.matrix);*/
		applyOutlineTransform(new ydPoint());
	}

	public void applyOutlineTransform(ydPoint shift) {
		matrix.reset();
		outline.reset();
		ydPoint midPoint=ydMath.midPoint(drawingPlane.boundTL, drawingPlane.boundBR);
		if(action.equals(Consts.DRAWING_ACTIONS_MOVE))
			outline.addRect(drawingPlane.boundTL.x, drawingPlane.boundTL.y, drawingPlane.boundBR.x, drawingPlane.boundBR.y, Direction.CCW);
		else if(action.equals(Consts.DRAWING_ACTIONS_ROTATE)){
			float x=ydMath.vectorToRads(shift);
			matrix.setRotate(x,midPoint.x, midPoint.y);
			outline.moveTo(midPoint.x, midPoint.y);
			outline.lineTo(midPoint.x, midPoint.y+drawingPlane.boundBR.x-midPoint.x);
			outline.addCircle(midPoint.x, midPoint.y, drawingPlane.boundBR.x-midPoint.x, Direction.CCW);
		}
		else if(action.equals(Consts.DRAWING_ACTIONS_SCALE))
			outline.addRect(drawingPlane.boundTL.x, drawingPlane.boundTL.y, drawingPlane.boundBR.x, drawingPlane.boundBR.y, Direction.CCW);
		
		
		//outline.addRect(drawingPlane.boundTL.x, drawingPlane.boundTL.y, drawingPlane.boundBR.x, drawingPlane.boundBR.y, Direction.CCW);
		//outline.transform(drawingPlane.matrix);
		invalidate();
		
	}

}
